package com.newmainsoftech.ant.script;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.tools.ant.types.LogLevel;
import org.aspectj.lang.annotation.Aspect;

public class AntOwnerAccessorImpl implements AntOwnerAccessorContract, AntLogMethodsContract {
	// Regarding AntOwnerAccessorContract interface -----------------------------------------------
	private Object owner;
		private OwnerRace ownerRace;
			public synchronized OwnerRace getOwnerRace() {
				return ownerRace;
			}
		public synchronized Object getOwner() {
			return owner;
		}
		public synchronized void setOwner( final Object owner) {
			if ( owner == null) {
				this.owner = null;
				ownerRace = null;
				return;
			}
			
			Class<?> ownerClass = owner.getClass();
			boolean isOwnerValid = false;
			for( OwnerRace ownerRaceObj : OwnerRace.values()) {
				Class<?> raceType = ownerRaceObj.getRaceType();
				try {
					ownerClass.asSubclass( raceType);
				}
				catch( ClassCastException exception) {
					continue; // for
				}
				this.owner = owner;
				ownerRace = ownerRaceObj;
				isOwnerValid = true;
			} // for
			if ( !isOwnerValid) {
				throw new IllegalArgumentException(
						String.format(
								"Type (=%1$s) of owner input object is not found in OwnerRace (%2$s) " 
								+ "or sub-class of them.",
								ownerClass.getName(), 
								Arrays.toString( OwnerRace.values())
								)
						);
			}
		}
	// --------------------------------------------------------------------------------------------
	
	// Regarding AntLogMethodsContract interface --------------------------------------------------
	public void log( final String msg) {
		Object ownerObj = getOwner();
			if ( ownerObj == null) return;
		
		try {
			Method logMethod = owner.getClass().getMethod( "log", String.class);
			logMethod.invoke( ownerObj, msg);
			logMethod.setAccessible( true);
		}
		catch( Throwable throwable) { 
			return;
		}
	}
	public void log( final String msg, int logLevel) {
		Object ownerObj = getOwner();
			if ( ownerObj == null) return;
		try {
			Method logMethod = owner.getClass().getMethod( "log", String.class, Integer.class);
			logMethod.invoke( ownerObj, msg, logLevel);
			logMethod.setAccessible( true);
		}
		catch( Throwable throwable) { 
			return;
		}
	}
	public void log( final String msg, final LogLevel logLevel) {
		int level = ((logLevel == null) ? LogLevel.INFO.getLevel() : logLevel.getLevel());
		log( msg, level);
	}
	// --------------------------------------------------------------------------------------------
}
